package com.lxmes.common.utils;

import java.util.concurrent.atomic.AtomicLong;

    public class  UniqueIdUtils {

    private static final AtomicLong sequence = new AtomicLong(0);
    private static final long WORKER_ID = 0L; // 工作节点 ID
    private static final long DATA_CENTER_ID = 0L; // 数据中心 ID
    private static final long SEQUENCE_BIT = 12; // 序列号占用的位数
    private static final long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT); // 最大序列号
    private static final long TIMESTAMP_LEFT_SHIFT = SEQUENCE_BIT; // 时间戳左移位数
    private static final long WORKER_ID_LEFT_SHIFT = SEQUENCE_BIT + 12; // 工作节点 ID 左移位数
    private static final long DATA_CENTER_ID_LEFT_SHIFT = SEQUENCE_BIT + 12 + 10; // 数据中心 ID 左移位数

    private volatile static long lastTimestamp = -1L; // 上一次的时间戳


    public static synchronized long generateUniqueId() {
        long currentTimestamp = System.currentTimeMillis();
        if (currentTimestamp < lastTimestamp) {
            throw new RuntimeException(
                    String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - currentTimestamp));
        }

        if (currentTimestamp == lastTimestamp) {
            long sequenceId = sequence.getAndIncrement();
            if (sequenceId > MAX_SEQUENCE) {
                sequence.set(0L);
                return generateUniqueId();
            }
            return currentTimestamp << TIMESTAMP_LEFT_SHIFT | sequenceId;
        } else {
            lastTimestamp = currentTimestamp;
            sequence.set(0L);
        }

        return currentTimestamp << TIMESTAMP_LEFT_SHIFT | sequence.get();
    }
}